package www.reagnetbox.com.scan;

import android.content.Context;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static android.hardware.usb.UsbConstants.USB_TYPE_CLASS;

public class UsbCdcDriver implements CommDriver {
	UsbCdcDriver.UsbSerialCommAbility mComm;
	Context mContext;
	UsbCommDev mDev;

	public static final int DEFAULT_READ_BUFFER_SIZE = 16 * 1024;
	public static final int DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024;

	public UsbCdcDriver(Context context, CommType dev) {
		mDev = (UsbCommDev) dev;
		mContext = context;
		mComm = new UsbCdcDriver.UsbSerialCommAbility(mContext, mDev);
	}

	@Override
	public List<CommTypeDescript> getSupportCommType() {
		List<CommTypeDescript> list = new ArrayList<>();
		list.add(CommTypeDescript.USB_CDC);
		return list;
	}

	@Override
	public CommAbility getCommAbility() {

		return mComm;
	}


	class UsbSerialCommAbility extends UsbAbility implements UsbSerialConst {


		int SET_LINE_CODING = 0x20;  // USB CDC 1.1 section 6.2
		int GET_LINE_CODING = 0x21;
		int SET_CONTROL_LINE_STATE = 0x22;
		int SEND_BREAK = 0x23;

		int send_acm_control(int bRequest, int value, byte[] data) {
			int len = 0;
			if (data != null) {
				len = data.length;
			}
			return deviceConnection.controlTransfer(USB_TYPE_CLASS | 1,
					bRequest, value, 0, data, len, 100);
		}


		int set_acm_dtr(boolean dtr, boolean rts) {
			int value = (rts ? 0x2 : 0) | (dtr ? 0x1 : 0);
			return send_acm_control(SET_CONTROL_LINE_STATE, value, null);
		}

		int set_acm_param() {
			//00 01 c2 00 --115200
			//08 -- 8 data bits
			//0--          (byte)(m_baudrate & 0xFF),
			//1--          (byte)((m_baudrate >> 8) & 0xFF),
			//2--          (byte)((m_baudrate >> 16) & 0xFF),
			//3--          (byte)((m_baudrate >> 24) & 0xFF),
			//4--          (byte)m_stopBits,
			//5--          (byte)m_parity,
			//6--          (byte)m_dataBits

			byte[] data = {0x00, (byte) 0xC2, 0x01, 0x00, 0x00, 0x00, 0x08};
			return send_acm_control(SET_LINE_CODING, 0, data);
		}


		public UsbSerialCommAbility(Context context, UsbCommDev dev) {
			super(context, dev);
		}


		@Override
		public void open() throws IOException {

			try {
				super.open();
				if (usbInterface == null || usbDevice == null) {
					throw new IOException("not find cdc usb");
				}
				set_acm_param();
				set_acm_dtr(true, false);
			} catch (IOException e) {
				throw e;
			}
		}


		@Override
		public void close() throws IOException {

			if (deviceConnection == null) {
				throw new IOException("Already closed");
			}

			deviceConnection.releaseInterface(usbInterface);
			super.close();

		}


	}
}
